
#include "dataparser.h"
#include <windows.h>

#include "tinyxml\tinyxml.h"
#include "jsoncpp\include\json\json.h"

namespace utils_snb
{

//////////////////////////////////////////////////////////////////////////
// CXmlDataParser

PSNBDATAOBJ CXmlDataParser::Parse(const char* lpszData)
{
	TiXmlDocument doc;
	//doc.Parse(lpszData, 0, TIXML_ENCODING_UTF8);
	doc.Parse(lpszData, 0);

	if (doc.Error())
		return NULL;

	TiXmlElement *pXml = new TiXmlElement(*doc.RootElement());
	return (PSNBDATAOBJ)pXml;
}

void CXmlDataParser::Free(PSNBDATAOBJ pObj)
{
	TiXmlElement *pElement = reinterpret_cast<TiXmlElement*>(pObj);
	if (!pElement || IsBadReadPtr(pElement, sizeof(TiXmlElement)))
		return;

	delete pElement;
}

PSNBDATAOBJ CXmlDataParser::GetObjectByKey(const char* lpszKey, PSNBDATAOBJ pObj)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement), sizeof(TiXmlElement)))
		return 0;

	TiXmlElement *pChild = xmlElement->FirstChildElement(lpszKey);
	return (PSNBDATAOBJ)pChild;
}

PSNBDATAOBJ CXmlDataParser::GetObjectByIdx(const int nIndex, PSNBDATAOBJ pObj)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement), sizeof(TiXmlElement)))
		return 0;

	TiXmlElement *pChild = xmlElement->FirstChildElement();
	int i = 0;
	while (pChild && i < nIndex)
	{
		pChild = pChild->NextSiblingElement();
		++i;
	}

	return (PSNBDATAOBJ)pChild;
}

long CXmlDataParser::GetLongByKey(const char* lpszKey, PSNBDATAOBJ pObj)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement),sizeof(TiXmlElement)))
		return 0;

	TiXmlElement *pChild = xmlElement->FirstChildElement(lpszKey);
	if (pChild)
		return atol(pChild->GetText());

	return 0;
}

long CXmlDataParser::GetLongByIndex(const int nIndex, PSNBDATAOBJ pObj)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement), sizeof(TiXmlElement)))
		return 0;

	TiXmlElement *pChild = xmlElement->FirstChildElement();
	int i = 0;
	while (pChild && i < nIndex)
	{
		pChild = pChild->NextSiblingElement();
		++i;
	}

	if (pChild)
		return atol(pChild->GetText());

	return 0;
}

void CXmlDataParser::GetStringByKey(const char* lpszKey, PSNBDATAOBJ pObj, std::string& strOut)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement), sizeof(TiXmlElement)))
		return;

	TiXmlElement *pChild = xmlElement->FirstChildElement(lpszKey);
	if (pChild && pChild->GetText())
	{
		strOut = pChild->GetText();
	}
}

void CXmlDataParser::GetStringByIndex(const int nIndex, PSNBDATAOBJ pObj, std::string& strOut)
{
	TiXmlElement *xmlElement = (TiXmlElement*)pObj;
	if (!xmlElement || IsBadReadPtr((xmlElement), sizeof(TiXmlElement)))
		return;

	TiXmlElement *pChild = xmlElement->FirstChildElement();
	int i = 0;
	while (pChild && i < nIndex)
	{
		pChild = pChild->NextSiblingElement();
		++i;
	}

	if (pChild && pChild->GetText())
	{
		strOut = pChild->GetText();
	}
}


//////////////////////////////////////////////////////////////////////////
// CJsonDataParser class

PSNBDATAOBJ CJsonDataParser::Parse(const char* lpszData)
{
	if (!lpszData || *lpszData == 0)
		return NULL;

	Json::Reader reader;
	Json::Value *pRoot = new Json::Value();

	if (!reader.parse(lpszData, (*pRoot), false))
		return NULL;

	return (PSNBDATAOBJ)pRoot;
}

void CJsonDataParser::Free(PSNBDATAOBJ pObj)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if (!jvalue || IsBadReadPtr((jvalue), sizeof(Json::Value)))
		return;

	delete jvalue;
}

PSNBDATAOBJ CJsonDataParser::GetObjectByKey(const char* lpszKey, PSNBDATAOBJ pObj)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if (!jvalue || IsBadReadPtr((jvalue),sizeof(Json::Value)) || jvalue->isNull())
		return NULL;

	Json::Value *jChildVal = (&(*jvalue)[lpszKey]);
	if (jChildVal->isObject() && !jChildVal->isNull())
		return reinterpret_cast<PSNBDATAOBJ>(jChildVal);

	return NULL;
}

PSNBDATAOBJ CJsonDataParser::GetObjectByIdx(const int nIndex, PSNBDATAOBJ pObj)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if (!jvalue || IsBadReadPtr((jvalue),sizeof(Json::Value)) || jvalue->isNull())
		return NULL;

	if (!jvalue->isValidIndex(nIndex))
		return NULL ;

	Json::Value *jChildVal = (&(*jvalue)[nIndex]);
	if (jChildVal->isObject() && !jChildVal->isNull())
		return reinterpret_cast<PSNBDATAOBJ>(jChildVal);

	return NULL;
}

long CJsonDataParser::GetLongByKey(const char* lpszKey, PSNBDATAOBJ pObj)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if ((!jvalue || IsBadReadPtr((jvalue), sizeof(Json::Value))) ||
		( jvalue->isNull() || !jvalue->isObject())) 
	{
		return 0;
	}

	Json::Value &jChildValue = (*jvalue)[lpszKey];

	if (!jChildValue.isNull())
	{
		if (jChildValue.isInt())
		{
			return (long)jChildValue.asInt();
		}
		else if (jChildValue.isUInt())
		{
			return (unsigned long)jChildValue.asUInt();
		}
		else if (jChildValue.isBool())
		{
			return (long)jChildValue.asBool();
		}
	}

	return 0;
}

long CJsonDataParser::GetLongByIndex(const int nIndex, PSNBDATAOBJ pObj)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if ((!jvalue || IsBadReadPtr((jvalue), sizeof(Json::Value))) || jvalue->isNull())
		return 0;

	if (!jvalue->isValidIndex(nIndex))
		return 0;

	Json::Value &jChildValue = jvalue[nIndex];

	if (!jChildValue.isNull())
	{
		if (jChildValue.isInt())
		{
			return jChildValue.asInt();
		}
		else if (jChildValue.isUInt())
		{
			return jChildValue.asUInt();
		}
		else if (jChildValue.isBool())
		{
			return jChildValue.asBool();
		}
	}

	return 0;
}

void CJsonDataParser::GetStringByKey(const char* lpszKey, PSNBDATAOBJ pObj, std::string& strOut)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if ((!jvalue || IsBadReadPtr((jvalue), sizeof(Json::Value))) ||
		( jvalue->isNull() || !jvalue->isObject())) 
	{
		return ;
	}

	Json::Value &jChildValue = (*jvalue)[lpszKey];
	if (jChildValue.isString()) 
	{
		strOut = jChildValue.asString();
	}
}

void CJsonDataParser::GetStringByIndex(const int nIndex, PSNBDATAOBJ pObj, std::string& strOut)
{
	Json::Value *jvalue = (Json::Value*)pObj;
	if ((!jvalue || IsBadReadPtr((jvalue),sizeof(Json::Value))) ||
		( jvalue->isNull())) 
	{
		return ;
	}

	if (!jvalue->isValidIndex(nIndex))
		return ;

	Json::Value &jChildValue = (*jvalue)[nIndex];
	if(jChildValue.isString() && !jChildValue.isNull() ) 
	{
		strOut = jChildValue.asString();
	}
}


} // namespace